#!/usr/bin/env python2.5
# -*- coding: UTF-8 -*-  

#Ref http://code.activestate.com/recipes/496743/
#Ref http://code.activestate.com/recipes/576663/
#Ref http://code.activestate.com/recipes/496702/
import re 
#import NMutl
#! TO DO: "na fygi import   re if posible"
def expandTxtWithURL (txt):  #! improvement set it to use a tag -
    r1 = r"(\b(http|https)://([-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]))"
    r2 = r"((^|\b)www\.([-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]))"
    return re.sub(r2,r'<a rel="nofollow" target="_blank" href="http://\1">\1</a>',re.sub(r1,r'<a rel="nofollow" target="_blank" href="\1">\1</a>',txt))

def getFromFileOrStr(contents, fileExtentions=['.html', '.js']):
    if isinstance(contents, basestring):
        if any ([contents.endswith (x) for x in fileExtentions]):
            #if contents.endswith(fileEnds):
            #print ['zzzz', contents]
            fl = open(contents, 'r') 
            rt = fl.read()
            fl.close()
            return [rt, True]
        else:return [contents, False]  
    elif isinstance(contents, file):
        return [contents.read() , False]  
    else:return ['', False] 
_html_mapping = (
    ("&", "&amp;"),
    ("  ", "&nbsp;&nbsp;"),
    (">", "&gt;"),
    ("<", "&lt;"),
    ('"', "&quot;"),
)
_nbsp='&nbsp;'
def escape(val):return escSpc(val)
def escSpc(val):return val.replace(' ', _nbsp)
def encode_html(obj):
    text = str(obj)
    for chr, enc in _html_mapping:
        text = text.replace(chr, enc)
    return text
def tmplSimple(template, dict, sectionNumber=None): 
    """this is a simple template system minimal in features but fast {$var_name$} for variables to be compatible with DJango templates
    '|||' section separation
    """
    exten = ['.html', '.js'] 
    delimiter=re.compile(r"""(\{\$.*?\$\})""",   re.MULTILINE|re.DOTALL|re.UNICODE) 
    tmp=getFromFileOrStr(template, exten)
    if tmp[1]:dir = ''.join(template.rpartition('/')[0:2])
    template=tmp[0]
    template=unicode(template, "utf-8") 
    if not sectionNumber is None:template=template.split(u'|||')[sectionNumber] 
    
    fa=re.findall(delimiter,template) 
    for el in fa:
        key=el[2:-2]
        val= dict.get(key, None)  
        if not val is None:template=template.replace(el,val)  
    return  template 
  
class NMtmpl(object):
    """
    teplate  can be a string or (a pathname if it endswith exten) 
    emitIncl argument 1 can be a NMtmpl object or a string or pathname  if pathname  starts with @ then @ is replaced with directory of current template
    emitIncl argument 2 is the namespace  of the include - if None defaults to parents namespace
    i.e ${emitIncl('@header_map_actions.html',None)}$  
    """
    exten = ['.html', '.js']
    start = '${'
    end   = '$}'
    dir = ''
    auto_emit = re.compile('(^[\'\"])|(^[a-zA-Z0-9_\[\]\'\"]+$)') 
    #delimiter = re.compile('%s(.*?)%s' % (re.escape('${'), re.escape('}$')), re.DOTALL)
    delimiter = re.compile(r"\$\{(.*?)\}\$", re.DOTALL) 
    #if len(start) != 2 or len(end) != 2:raise ValueError('delimiters must be 2 chrs')
    def __init__(self, template):
        self._template = getFromFileOrStr(template, self.exten)
        if self._template[1]:self.dir = ''.join(template.rpartition('/')[0:2])
        self._template=self._template[0]
        self._code = None 
    def jotc(self):
        template=self._template
        offset = 0
        tokens = []
        for i, part in enumerate(self.delimiter.split(template)):
            part = part.replace('\\'.join(list(self.start)), self.start)
            part = part.replace('\\'.join(list(self.end)), self.end)
            if i % 2 == 0:
                if not part: continue
                part = part.replace('\\', '\\\\').replace('"', '\\"')
                part = '\t' * offset + 'emit("""%s""")' % part
            else:
                part = part.rstrip()
                if not part: continue
                if part.lstrip().startswith(':'):
                    if not offset:
                        raise SyntaxError('no block statement to terminate: ${%s}$' % part)
                    offset -= 1
                    part = part.lstrip()[1:]
                    if not part.endswith(':'): continue
                elif self.auto_emit.match(part.lstrip()):
                    part = 'emit(%s)' % part.lstrip()
                lines = part.splitlines()
                margin = min(len(l) - len(l.lstrip()) for l in lines if l.strip())
                part = '\n'.join('\t' * offset + l[margin:] for l in lines)
                if part.endswith(':'):
                    offset += 1
            tokens.append(part)
        if offset:
            raise SyntaxError('%i block statement(s) not terminated' % offset)
        self._code = compile('\n'.join(tokens), '<templite %r>' % template[:20], 'exec') 
        self.NMcodeorg=('\n'.join(tokens), '<templite %r>' % template[:20], 'exec')        #debug
        self.NMcodeanal=[tokens,'<templite %r>' , template[:20], 'exec' ]                  #debug 
    def render(self, __namespace=None, **kw):
        """
        renders the template according to the given namespace. 
        __namespace - a dictionary serving as a namespace for evaluation
        **kw - keyword arguments which are added to the namespace
        """
        if self._code is None:self.jotc()
        self.namespace = {}
        if __namespace: self.namespace.update(__namespace)
        if kw: self.namespace.update(kw)
        if 'emit' not in self.namespace:
            self.namespace['emit'] = self.emiter
            self.namespace['emitIncl'] = self.emiterIncl 
        self._output = []
        eval(self._code, self.namespace)  
        return ''.join(self._output)
    def emiterIncl(self, subcontents, nspace=None):  
        if nspace == None: nspace=self.namespace
        if not isinstance(subcontents,  NMtmpl):
            subcontents=subcontents[0].replace('@',self.dir)+subcontents[1:]  
            subcontents=NMtmpl(subcontents) 
            if len(self._output) > 0:
                shiftchrs=self._output[-1].rpartition('\n')[2]   
                subcontents._template= subcontents._template.replace('\n', '\n'+ shiftchrs)  
              
        subcontents.render(nspace)
    def emiter(self, *args): 
        for a in args:  
            self._output.append(str(a)) 
    #      @classmethod
    #      def getTemplate(cls, template):
    #          if isinstance(template, basestring):
    #              if template.endswith(cls.exten):
    #                 cls.dir = ''.join(template.rpartition('/')[0:2])
    #                 fl = open(template, 'r')
    #                 rt=fl.read()
    #                 fl.close()
    #                 return rt
    #              else:return template  
    #          elif isinstance(template, file):
    #               return template.read()
    #          else:return None 
      

class attrs(object):
    __slots__ = ['contents']  
    def __init__(self, attrs=''):
        self.contents=''
        if isinstance(attrs, dict): 
            for it in attrs:  
                self[it]=attrs[it]  
        else:
            self.contents=attrs
    def __setitem__(self, attr, val):  
        del self[attr]
        self.contents = "%s%s%s%s%s%s%s" % (self.contents,'' if self.contents == '' else ' ',  attr ,  '=' ,  "\"" ,  val ,  "\"") 
        return val
    def getAttrLst(self, attr):
        rt=self[attr]
        if rt !='':return rt.split(' ')
        else:return [] 
    def hasSubAttr(self, attr, subAttr):
        return subAttr in self.getAttrLst(attr)
    def append(self, attr, val):
        res=self[attr]
        if res =='':
            self[attr]=val
        else:
            if val !='':self[attr]= res  + ' ' + val
    def __getitem__ (self,attr):
        return self.strAttr(attr)[len(attr)+2:-1] 
     
    def strAttr(self, attr, start=0):
        st=str(self.contents)
        idxSt=st.find(attr +'=' , start) 
        if idxSt == 0 or idxSt > 0 and st[idxSt - 1]==' ':
            idxEnd = st.find('\"', idxSt+len(attr)+2) 
            if idxEnd >- 1:return st[idxSt:idxEnd+1]
            else: return ''
        elif idxSt >0:
            return self.strAttr(attr, idxSt+1)
        else:
            return ''
    def __delitem__ (self, attr):
        st = self.strAttr(attr)
        if st !='':self.contents = self.contents.replace(st, '').strip() 
    def __str__  (self): return self.contents.__str__() 
    def __call__ (self): return self.contents.__str__()
      
DocType = 1   # 0 ='XHTML' 1= html4 strict      
class tag(object):
    __slots__ =  ['_name','contents', 'attributes', '_expand', '_nonclosing']
    _cnstEOL=u'\n'
    _nonclosing=False
    #_nonclosing=['meta', 'link', 'col' , 'img',  'input']
    def __init__(self, contents='', attributes='', name=None): 
        if isinstance(attributes,attrs):
            self.attributes = attributes 
        else:   
            self.attributes = attrs(attributes)
        self.contents = u''
        self._name = self.__class__.__name__ if name is None else name 
        self._expand='\t' 
        self.insertContents(contents)
    def validateContents(self, conts):
        return True
    #          if isinstance(conts, basestring):      return True 
    #          elif isinstance(conts, (list, tuple)): return all([isinstance(it, tag) for it in conts]) 
    #          else:                                  return False 
    def validationError(self,conts):
        raise Exception ('Err On Tag Validation: ',type(self), conts) 
    def insertContents(self, contents,before=None):  #! 1 level lists only 
        if isinstance(contents, str):contents = unicode(contents,  'utf-8')  #@unicode
        if self.validateContents(contents):
            if self.contents != '' and not isinstance(self.contents, list):self.contents = [self.contents]
            if isinstance(self.contents, list):
                if before is None:
                    if isinstance(contents, list):self.contents.extend(contents)
                    else:self.contents.append(contents)
                else:
                    if isinstance(contents, list):
                        for it in reversed(contents):
                            self.contents.insert(before, it)
                    else:self.contents.insert(before, contents)  
            else:self.contents = contents 
        else:
            self.validationError (contents)  
        return contents
    def __setitem__(self,i, val):
        self.contents[i]=val
        return val
    def __getitem__(self,i): 
        return self.contents[i]
    
    def attrGetClass(self):           return self.attrGet('class')
    def attrIsOfClass(self, subAttr): return self.attributes.hasSubAttr('class', subAttr)
    def attrGetId(self):              return self.attrGet('id')
    def attrSetClass(self, val):      return self.attrSet('class', val)
    def attrSetId(self, val):         return self.attrSet('id', val)
    def attrSetStyle(self, val):      return self.attrSet('style', val)
    def attrSet(self, attr, val):     self.attributes[attr]=val  
    def attrGet(self, attr):          return self.attributes[attr]
    def attrGetTitle(self):           return self.attrGet('title')
    def attrSetTitle(self, val):      return self.attrSet('title', val)
    def attrGetName(self):            return self.attrGet('name')
    def attrSetName(self, val):       return self.attrSet('name', val)  
    def attrDel(self, attr):          del self.attributes[attr]
    def attrAppend(self, attr, val):  self.attributes.append(attr,val) 
    def attrAppendClass(self, val):   self.attributes.append('class',val)
    def attrAppendCnt(self, cnt, ststr='nm-'):  self.attrAppendClass('%s%s%02d %s%s' %(ststr,'cnt', cnt, ststr,'even' if cnt % 2 == 0 else 'odd') )
    
    def setExpand(self, expandchrs):self._expand=expandchrs 
    #      def appendContents(self, contents):
    #          if self.contents != '' and not isinstance(self.contents, list):self.contents = [self.contents]
    #          if isinstance(contents, list):
    #             for it in contents:self.appendContents(it)
    #          else:
    #             self.contents.append(contents)  
    def name(self):return self._name
    def __len__(self): 
        if isinstance(self.contents, list):   return sum([len (item) for item in self.contents]) + 1  
        else: return 1
    def _toStrOpen(self):
        if DocType == 0:
            return '<'+ self.name() + ('' if str(self.attributes) =='' else ' ') + str(self.attributes) + ('>' if self.contents !='' else ' ')
        elif DocType == 1:
            #$ org - return '<'+ self.name() + ('' if str(self.attributes) =='' else ' ') + str(self.attributes) + '>' # ('/>' if self.name() in self._nonclosing else '>')
            return '<'+ self.name() + ('' if str(self.attributes) =='' else ' ') + str(self.attributes) + (' ' if self._nonclosing else '>')  
            #return '<'+ self.name() + ('' if str(self.attributes) =='' else ' ') + str(self.attributes) +  ('/>' if self._nonclosing else '>')
            #return '<'+ self.name() + ('' if str(self.attributes) =='' else ' ') + str(self.attributes) +  '>'  
    def _toStrAttrs(self):return str(self.attributes)
    def _toStrContents(self, subcontents):
        if isinstance(subcontents, list):
            return ''.join([self._toStrContents(item) for item in subcontents])
        elif isinstance(subcontents,tag):
            return subcontents.toStr()
        else :
            return subcontents    
    def _toStrClose(self):
        if DocType == 0:
            return '</' + self.name() +  '>' if self.contents !='' else '/>'
        elif DocType == 1: 
            if self._nonclosing:   # self.name() in self._nonclosing: 
                return ' />'
            else:
                return '</' + self.name() +  '>' # if self.contents !='' else '>'  
    def toStr(self):
    #          if self._nonclosing:
    #             return "%s %s %s%s" %(self._toStrOpen() , self._toStrAttrs(), self._toStrContents(self.contents) ,  self._toStrClose()  )
    #          else:
    #            return "%s %s>%s%s" %(self._toStrOpen() , self._toStrAttrs(),    self._toStrContents(self.contents) ,  self._toStrClose()  )
          
        return self._toStrOpen() + self._toStrContents(self.contents)  + self._toStrClose() 
    def genStr(self, depth=0):
        def expand():return self._expand * depth
        if isinstance (self.contents, basestring):  
            yield "%s%s%s%s%s" % (expand(),self._toStrOpen(), self.contents.replace('\n', '\n'+expand()), self._toStrClose(), self._cnstEOL)
        if isinstance(self.contents,tag):
            yield expand() + self._toStrOpen()  + self._cnstEOL
            for val in self.contents.genStr(depth+1):
                yield val
            yield expand() + self._toStrClose() + self._cnstEOL
        elif isinstance(self.contents,list):
            yield  expand() + self._toStrOpen()  + self._cnstEOL
            for item in self.contents:  
                if isinstance(item, basestring):yield item
                else: 
                    for val in item.genStr(depth+1): 
                        yield val 
            yield  expand() + self._toStrClose() + self._cnstEOL
    #          elif isinstance(self.contents,GVtable):
    #            rtv='\n'+ str(self.contents)+'\n'
    #            yield "%s%s%s%s%s" % (expand(),self._toStrOpen(), rtv.replace('\n', '\n'+expand()), self._toStrClose(), self._cnstEOL)
    def genStrStr(self, depth=0):
        st=''
        for vl in self.genStr(depth):st += vl  
        return st     
    def strpp(self, st='', depth=0):
        def expand():return self._expand * depth
        st += expand() + self._toStrOpen() 
        if isinstance(self.contents,tag):
            st += self._cnstEOL
            st = self.contents.strpp(st,depth + 1) 
        elif isinstance(self.contents, list):
            st += self._cnstEOL
            for item in self.contents:
                st = item.strpp(st,depth + 1)
        else:
            st += self.contents
        if isinstance(self.contents, (list, tag)) :st += expand() 
        st ="%s%s%" %(st,  self._toStrClose() ,  self._cnstEOL)
        return st
    def genStrNT(self, depth=0,TagOpen=u'',TagClose=u', '  ,EOLStr=u'',expandStr=u''): 
        def expand():return expandStr *  depth
        if isinstance (self.contents, basestring):  
            yield "%s%s%s%s%s" % (expand(),TagOpen, self.contents.replace('\n', '\n'+expand()), TagClose, EOLStr)
        if isinstance(self.contents,tag):
            yield expand() + TagOpen + EOLStr
            for val in self.contents.genStrNT(depth+1, TagOpen, TagClose, EOLStr, expandStr):
                yield val
            yield expand() + TagClose + EOLStr
        elif isinstance(self.contents,list):
            yield  expand() + TagOpen + EOLStr
            for item in self.contents:  
                if isinstance(item, basestring):yield item
                else: 
                    for val in item.genStrNT(depth+1, TagOpen, TagClose, EOLStr, expandStr): 
                        yield val 
            yield  expand() + TagClose + EOLStr    
    def genStrNTStr(self, depth=0,TagOpen=u'',TagClose=u', '  ,EOLStr=u'',expandStr=u'' ):
        st=u''
        for vl in self.genStrNT(depth=0,TagOpen=u'',TagClose=u', '  ,EOLStr=u'',expandStr=u'' ):
            st += vl  
        return st  
    def genStrNTContents(self):
        st=u''
        for vl in self.genStrNT(depth=0,TagOpen=u'',TagClose=u'XAX',EOLStr=u'',expandStr=u'' ):
            st += vl  
        st=re.sub("<br>|(XAX){1,100}",',',st)
        return st[2:-1]   
    
    #      def gen(self):
    #          if isinstance(self.contents, list):
    #             for item in self.contents:
    #                 if isinstance(item , tag):
    #                    for it in item.gen():yield it
    #          else:
    #              if isinstance(self.contents, tag):
    #                  for it in item.gen():yield it 
    #              else:
    #                  yield self 
    def saveToFile(self, fname):
        fileOut = open(fname, 'w')
        fileOut.write(self.genStrStr()) 
        fileOut.close()
    def __add__(self, other):
        return self.genStrStr() + (other.genStrStr() if isinstance(other, tag) else other)
    __str__  =  genStrStr
    __call__ =  genStrStr   
    __repr__ =  toStr
class tagNC(tag):
    __slots__ =  []
    _nonclosing=True
class mformatGeo(tag):
        __slots__ =  []
    #contents='', attributes='', name=None   
        def __init__(self,latitude, longitude, contents='', name='span'): 
            tag.__init__(self,contents, name=name)
            self.attrSetClass('geo')
            self.insertContents(span(latitude, 'class="latitude"'))
            self.insertContents(span(longitude, 'class="longitude"'))
class mformatGeoAbr(tag):
        __slots__ =  []
    #contents='', attributes='', name=None   
        def __init__(self,latLng, contents=''): 
            tag.__init__(self,contents, name='abbr')
            self.attrSetClass('geo')
            self.attrSetTitle(latLng)           
            
class incl(tag):
    __slots__ =  []
    def __init__(self, contents=''):tag.__init__(self,getFromFileOrStr(contents)[0])  
    def _toStrOpen(self) :return''
    def _toStrClose(self):return''
class dummytag(tag):
    __slots__ =  []
    def __init__(self, contents=''):tag.__init__(self,contents)   
    def _toStrOpen(self) :return''
    def _toStrClose(self):return''


class div(tag):__slots__    =[]
class span(tag):__slots__   =[]
class p(tag):__slots__      =[] 
class sup(tag):__slots__    =[] 
class sub(tag):__slots__    =[] 
class h1(tag):__slots__     =[] 
class h2(tag):__slots__     =[]
class h3(tag):__slots__     =[] 
class h4(tag):__slots__     =[] 
class h5(tag):__slots__     =[]
class h6(tag):__slots__     =[]  
def h1_6(caption, level):
    return tag(caption, 'class=\"nm-hd\"',  name='h'+str(min(6,level)))
class abbr(tag):__slots__     =[]  
class acronym(tag):__slots__     =[] 
class style(tag):
    def __init__(self, contents='', attributes=''):
        tag.__init__(self,contents, attributes)  
        self.attrSet("type", "text/css") 
class remark(tag):
    __slots__ =  [] 
    def _toStrOpen(self) :return '<!-- '
    def _toStrClose(self):return  ' -->'   
 
class form(tag):
    __slots__ =  []  
    def __init__(self, contents='', attributes='',  method="get", action=False):
        tag.__init__(self,contents, attributes) 
        if method:self.attrSet('method', method)
        if action:self.attrSet('action', action)
class input(tag): 
    _nonclosing=True
    def __init__(self, contents='', attributes='',  value=False, type='button'):
        tag.__init__(self,contents, attributes) 
        if value:self.attrSet('value', value) 
        self.attrSet('type', type) 
class select(tag):
    __slots__ =  []  
    def __init__(self, optionslst=[], attributes=''):
        tag.__init__(self,"", attributes) 
        cnt=0;
        for opt in optionslst:
            cnt +=1
            curOption=option(opt)
            curOption.attrAppendCnt(cnt)
            self.insertContents(curOption)     
                        
class option(tag):
    __slots__ =  []  
    def __init__(self, contents='', attributes='',  value=False, selected=False):
        tag.__init__(self,contents, attributes) 
        if value:self.attrSet('value', value)
        if selected:self.attrSet('selected', 'selected') 
class button(tag):
    __slots__ =  []  
    def __init__(self, contents='', attributes='',  OnClick=False):
        tag.__init__(self,contents, attributes) 
        if OnClick:self.attrSet('OnClick', OnClick) 
        
class a(tag):
    __slots__ =  []
    def __init__(self, contents='', attributes='', href=False, target=False, title=False):
        tag.__init__(self,contents, attributes) 
        if href:self.attrSetHref(href)
        if title: self.attrSetTitle(title)
        if target:self.attrSetTarget(target) 
    def attrGetHref(self):             return self.attrGet('href')
    def attrSetHref(self, val):        return self.attrSet('href', val) 
    def attrGetTarget(self):           return self.attrGet('target')
    def attrSetTarget(self, val):      return self.attrSet('target', val) 
 
class img(tag):
    __slots__ =  []
    _nonclosing=True
    def __init__(self, src=False, alt=False, title=False, height=False, width=False):
        tag.__init__(self) 
        if src:   self.attrSetSrc(src)
        if alt:   self.attrSetAlt(alt)
        if title: self.attrSetTitle(title)
        if height: self.attrSetHeight(height)
        if width: self.attrSetWidth(width)
    def attrGetSrc(self):             return self.attrGet('src')
    def attrSetSrc(self, val):        return self.attrSet('src', val)
    def attrGetAlt(self):             return self.attrGet('alt')
    def attrSetAlt(self, val):        return self.attrSet('alt', val)
    def attrGetHeight(self):          return self.attrGet('height')
    def attrSetHeight(self, val):     return self.attrSet('height', val)
    def attrGetWidth(self):           return self.attrGet('width')
    def attrSetWidth(self, val):      return self.attrSet('width', val) 
class ul(tag):
    __slots__ =  []
    class li(tag):__slots__ =  [] 
    def __init__(self, contents='', attributes=''):
        tag.__init__(self,'',  attributes)
        self.attrSetClass('nm-lev-00')
        if contents !='':   
            rt=lstToTag(contents, type(self), self.li) 
            if isinstance(rt, type(self)): 
                if isinstance(rt.contents, (basestring, tag)):self.contents=rt
                else:
                    for it in rt.contents: self.insertContents(it)
        else:
            self.contents=rt  
    def validateContents(self, conts):
        if isinstance(conts, (basestring, tag)):      return True 
        elif isinstance(conts, (list, tuple)): return all([isinstance(it, (tag, basestring)) for it in conts]) 
        else:return False       
class ol(ul):__slots__ =  [] 

def lstOfTags(item, cls=p):  
    if isinstance(item, list): 
        return  [lstOfTags(it, cls) for it in item]
    else:
        return cls(item)  
#def itemToUlLi(arg, dowhat=lambda x: x):
#     if isinstance(arg, list):
#        return ul([itemToUlLi(it, dowhat)  for  it in arg ]  )
#     else: 
#        return (ul.li(dowhat(arg))) 

def itemToUlLi(arg, dowhat=lambda x: x, byme=False):
    if isinstance(arg, list):  
        return tag([itemToUlLi(it, dowhat, True)  for  it in arg ], '', 'ul' ) if byme else dummytag([itemToUlLi(it, dowhat, True)  for  it in arg ] )
    else: 
        return (ul.li(dowhat(arg))) 
        
#def lstToUlLi(arg, byme=False): 
#     if isinstance(arg, list):  
#        return tag([itemToUlLi(it, dowhat, True)  for  it in arg ], '', 'ul' ) if byme else dummytag([itemToUlLi(it, dowhat, True)  for  it in arg ] )
#     else: 
#        return (ul.li(dowhat(arg)))   
  
def lstToUL(arg, dowhat=lambda x: x, byme=False):
    def myUL(it):  
        return   tag(it , '', 'ul')   
    def ff (it):
        return ul.li(dowhat(it))
         
    #return  ul.li([arg[0], myUL([ ul.li(it)  for it in  arg[1]] ) ] )   
    if  isinstance(arg, list): 
        return  ul.li([ dowhat(arg[0]), myUL([ lstToUL(it, dowhat) if isinstance(it, list) else ul.li(dowhat(it))  for it in  arg[1]] ) ] ) 
    else:
        return  ul.li(dowhat(arg) )
#def lm(arg, byme=False):
#    def myUL(it):  
#        return   tag(it , '', 'ul')   
#    def myRes(it):  
#        pass  
#    #return  ul.li([arg[0], myUL([ ul.li(it)  for it in  arg[1]] ) ] )    
#    return  ul.li([arg[0], myUL([ lm(it) if isinstance(it, list) else ul.li(it)  for it in  arg[1]] ) ] )
    
#def genLstToUlLi(arg, dowhat=lambda x: x, byme=False):     
#    if isinstance(arg, list):  
#        if  byme:
#            print 'ByME'
#            tmpUL= tag([itemToUlLi(it, dowhat, True)  for  it in arg ], '', 'ul' )
#            lastLI.insertContents(tmpUL)
#            yield  lastLI
#        else:
#            print 'BYME NOT'
#            tmpUL= dummytag([itemToUlLi(it, dowhat, True)  for  it in arg ] ) 
#            yield tmpUL
#    else: 
#        print 'LastLI'
#        lastLI=ul.li(dowhat(arg) )
#        yield lastLI
        

#def genItemToUlLi(lst depth=0):
#      def expand():return self._expand * depth
#      if isinstance (self.contents, basestring): 
#         ##print self.contents[1:10] 
#         yield "%s%s%s%s%s" % (expand(),self._toStrOpen(), self.contents.replace('\n', '\n'+expand()), self._toStrClose(), self._cnstEOL)
#      if isinstance(self.contents,tag):
#         yield expand() + self._toStrOpen() + self._cnstEOL
#         for val in self.contents.genStr(depth+1):
#             yield val
#         yield expand() + self._toStrClose() + self._cnstEOL
#      elif isinstance(self.contents,list):
#         yield  expand() + self._toStrOpen() + self._cnstEOL
#         for item in self.contents:  
#             if isinstance(item, basestring):yield item
#             else: 
#                 for val in item.genStr(depth+1): 
#                     yield val 
#         yield  expand() + self._toStrClose() + self._cnstEOL

#def itemToUlLiInsertUlToLi(tg):
#    ContLst=tg.contents
#    for ix, item in enumerate (ContLst):
#        if isinstance(item, ul.li) and  ix<len(ContLst)-1 and ContLst[ix+1]._name=='ul': 
#            print 'found', ix
#            item.insertContents(ContLst[ix+1])
#            #item.insertContents (itemToUlLiInsertUlToLi(ContLst[ix+1]) )  
#            return   itemToUlLiInsertUlToLi ([item, ContLst[:]                    
#    return tg       
# 
#def itemToUlLi2(arg, dowhat=lambda x: x, startTag=dummytag()):
#    print startTag()
#    if isinstance(arg, list):
#        startTag.insertContents(tag([itemToUlLi(it, dowhat, startTag)  for  it in arg ], '', 'ul' ))  
#        #return tag([itemToUlLi(it, dowhat, True)  for  it in arg ], '', 'ul' ) if byme else dummytag ([itemToUlLi(it, dowhat, True)  for  it in arg ] )
#    else: 
#        startTag=ul.li(dowhat(arg))
#        return startTag
        
       
def lst_toTag(l, tag, attrs=''):
    for li in l: 
        if  isinstance(li, basestring): 
            l[l.index(li)] = tag(li, attrs)
        else: 
            lst_toTag(li, tag, attrs)  
            
def lst_toTagBookMark(l, attrs='', baseUri=''):
    for li in l: 
        if  isinstance(li, basestring): 
            l[l.index(li)] = a(li,attrs, baseUri+"#"+li)
        else: 
            lst_toTagBookMark(li,  attrs)   
 
def lstToTag2(item, listCls=ul, itemCls=ul.li, level=0, lastItem=False):  
    if isinstance(item, (basestring, tag)): 
        lastItem=itemCls(item)
        return lastItem
       
    elif isinstance(item, list): 
        if not lastItem: ContLst=listCls()
        else:ContLst=lastItem 
        for it in item: 
            vl=lstToTag2(it, listCls, itemCls, level+1, lastItem) 
            ContLst.insertContents(vl)   
        return ContLst  
   
def lstToTag(item, listCls=div, itemCls=p, level=0):  
    if isinstance(item, (basestring, tag)): 
        return itemCls(item)
    elif isinstance(item, list): 
        ContLst=listCls()
        ContLst.attrSetClass("nm-lev-" + "%02d" % level)
        cnt=-1
        for it in item:
            cnt +=1
            vl=lstToTag(it, listCls, itemCls, level+1)
            vl.attrAppendCnt(cnt) 
            ContLst.insertContents(vl)   
        return ContLst      
            
class table(tag): 
    class caption(tag):__slots__ =  []
    class colgroup(tag):__slots__ =  []
    class thead(tag):__slots__ =  []
    class tbody(tag):__slots__ =  [] 
    class tr(tag):__slots__ =  []
    class td(tag):__slots__ =  []
    class th(tag):__slots__ =  []
    class tfoot(tag):__slots__ =  [] 
    class col(tag):
        __slots__ =  []
        _nonclosing=True
    tcaption=None 
    tcolgroup=None
    head=None 
    body=None 
    foot=None  
    def __init__(self, contentslst = [], attributes='',caption = False, headerlst = [], footerlst= [], tagColums=True, contentsStr=None):
        tag.__init__(self,'',  attributes) 
        if caption:self.insertCaption (caption)   
        if tagColums and contentslst:  
            self.tcolgroup=self.colgroup()  
            NumOfColumns = len (contentslst[0]) if isinstance(contentslst[0], list) else len(contentslst) 
            #for i in range (NumOfColumns):self.tcolgroup.insertContents (tag('', "class=\"nm-tcol" + str(i)  +"\"" , 'col')) 
            for i in range (NumOfColumns):self.tcolgroup.insertContents (self.col('', "class=\"nm-tcol" + str(i)  +"\"" )) 
            self.insertContents(self.tcolgroup)  
        if headerlst !=[] :  
            self.head=self.thead(self.trFromList(headerlst))
            self.insertContents(self.head) 
        if contentslst !=[]:  
            self.body=self.tbody(self.trFromList(contentslst)) 
            self.insertContents(self.body)
            self.attrAppendClass('nm-t-rows-' + str(len(contentslst)))
        elif isinstance (contentsStr, basestring): #incase we have a td tr str 
            self.body=self.tbody("%s%s%s" %(self._cnstEOL, contentsStr, self._cnstEOL) )
            self.insertContents(self.body)   
        if footerlst !=[]:
            self.foot=self.tfoot(self.trFromList(footerlst))
            self.insertContents (self.foot)
    def insertCaption(self, val='', atrs=''):
        self.tcaption = self.caption(val, atrs)
        self.insertContents(self.tcaption, 0)
    @classmethod
    def trFromList(cls, lst, row=0):
        def tdr(it):
            tr=cls.tr(it)
            tr.attrAppendCnt(row)
            return tr
            #return cls.tr(it, '%s%02d %s%s' %("class=\"nm-t-r",  row ,  'nm-t-even'  if row % 2 == 0 else 'nm-t-odd',  "\""))
        if isinstance(lst[0], list):
            return [cls.trFromList(item, lst.index(item)+1) for item in lst]
        else:return tdr([cls.td(it) for it in lst]) 
class dividerTable(table):
    def __init__(self, *args, **kargs):
        table.__init__(self, *args, **kargs) 
        self._name='table' 
        self.attrAppendClass('nm-dividerTbl')
        self.setwidths()
    def setwidths(self):
        self.attrAppend('width', '100%')
          
class noscript(tag):__slots__ =  []          
class script(tag):
    __slots__ =  []
    def __init__(self,  contents='', src=False):
        #if contents!='':contents=dummytag(contents) 
        tag.__init__(self, contents)  
        self.attrSet('type', 'text/javascript')
        self.attrSet('charset', 'utf-8')
        if src:self.attrSetSrc(src)  
    def attrSetSrc(self, src):self.attrSet('src',src)
    def insertContents(self, contents):  
        #super(type(self), self).insertContents(dummytag(contents)) 
        if contents !='' :
            if isinstance(contents, tag): return tag.insertContents(self, contents) 
            else:return tag.insertContents(self, dummytag(contents)) 
            
            #tag.insertContents(self, dummytag(contents), None)
#<script type="text/javascript" src="http://www.google.com/jsapi"></script>
class scriptGjsapi(script):
    __slots__ =  []
    def __init__(self):
        script.__init__(self,src = "http://www.google.com/jsapi")
        self._name='script'
class scriptGMapsV3(script):
    __slots__ =  []
    def __init__(self):
        script.__init__(self,src = "http://maps.google.com/maps/api/js?sensor=false")
        self._name='script'

class scriptSingleton(script):
    __slots__ =  []
    def __init__(self,varName, **kargs):
        script.__init__(self)
        self._name='script'
        print kargs 
        vars = ""
        for k in kargs.keys():
            val = "\"" + kargs[k] + "\"" if isinstance(kargs[k], basestring) else  str(kargs[k])
            vars += "\t" + k + ": " + val  + ",\n" 
        vars=vars[:-2]+'\n'    
        self.contents="\n\tvar %s = {\n %s\t}\n" %(varName, vars) 
class scriptTest(script):
    def __init__(self):
        script.__init__(self) 
        self._name='script'
        cnts="""
        google.load('visualization', '1.1', {packages:['imagechart']});
        google.setOnLoadCallback(drawChart);
    
        function drawChart() {
          var dataTable = new google.visualization.DataTable();
          dataTable.addColumn('string');
          dataTable.addColumn('number');
          dataTable.addRows(3);
          dataTable.setValue(0, 0, 'DZ');
          dataTable.setValue(0, 1, 0);
          dataTable.setValue(1, 0, 'EG');
          dataTable.setValue(1, 1, 100);
          dataTable.setValue(2, 0, 'MG');
          dataTable.setValue(2, 1, 50); 
          var options = {cht: 't', chtm: 'europe', chco: 'FFFFFF,EEEEEE,000000', chs: '440x220'};
          var chart = new google.visualization.ImageChart(document.getElementById('Location'));
          chart.draw(dataTable, options);
        } 
       """
        self.insertContents(dummytag(cnts))
#class scriptPanoramio(script):
#      def __init__(self, coordinates = "48.85,2.35", displayTagId='nm_id_panoramioCont', ): 
#          script.__init__(self) 
#          self._name='script'
        
#class scriptGMV3(script):
#      def __init__(self, contents=''): 
#          script.__init__(self)
#          self._name='script'
#          tmp=""" 
#              function initializeGmap() {
#                var latlng = new google.maps.LatLng(-34.397, 150.644);
#                var myOptions = {
#                  zoom: 8,
#                  center: latlng,
#                  mapTypeId: google.maps.MapTypeId.ROADMAP
#                };
#                var map = new google.maps.Map(document.getElementById("Country"), myOptions);
#              } 
#             """
#          self.insertContents(dummytag(tmp))
class scriptGV(script): 
    #<![CDATA[document.write("H") ? 
    def __init__(self, contents='', GVversion='1'): 
        script.__init__(self)
        self.VisCnt=0
        self._name='script'
        self.__tablevarnameLst__=[]
        self.packagesLst = []
        self.GVversion=GVversion 
        self.GVpackages=(dummytag())
        #self.GVpackages.insertContents(self._JSloadPackages())
        self.insertContents(self.GVpackages)
        self.insertContents('google.setOnLoadCallback(funOnLoad);')
        self.GVtables = dummytag(dummytag('// table definitions' + '//'*5))  
        self.Onload=dummytag()
#        jsf="""
#      var chart = new google.visualization.PieChart(document.getElementById('LandUse'));
#      chart.draw(LandUse, {width: 400, height: 240, is3D: true, title: 'Land Use',backgroundColor: 'transparent',legendBackgroundColor: 'transparent'});
#            """       
        self.Onload.insertContents(dummytag('function funOnLoad() {')) 
        self.Onload.insertContents(self.GVtables)
        self.ActionScript=dummytag()
        self.Onload.insertContents(self.ActionScript)  
        self.Onload.insertContents(dummytag('}'))
        self.insertContents(self.Onload)
    def insertGVtable(self, aGVtable):
        self.GVtables.insertContents(dummytag(str(aGVtable)))
    def insertActionScript(self,script):
        self.ActionScript.insertContents(dummytag(script)) 
    def insertVisualization(self, elemId, GVpackage, GVProps='',  GVtableOrName=None, rows=[], cols=[], tableProps='', bgncolor='transparent', lgntxtcol='gray'): 
        if isinstance(GVtableOrName, GVtable):
            tablename = GVtableOrName.varname
            if GVtableOrName not in self.__tablevarnameLst__:
                self.__tablevarnameLst__.append (tablename)
                self.insertGVtable(GVtableOrName)  
        elif not  GVtableOrName in self.__tablevarnameLst__:
            tablename = GVtableOrName if isinstance(GVtableOrName, basestring) else elemId
            GVtableOrName = GVtable(tablename, rows, cols, tableProps) 
            self.insertGVtable(GVtableOrName)
            self.__tablevarnameLst__.append (tablename)
        else:
            tablename = GVtableOrName
        self.VisCnt += 1
        if not GVpackage.lower() in self.packagesLst:self.packagesLst.append (GVpackage.lower())
        #if GVProps=='':GVProps="{width: 560, height: 240, is3D: true,backgroundColor: '#cb9f65',legendBackgroundColor: '#f0bc77',legend:'label',enableTooltip:true,legendFontSize:8,titleFontSize:0}"
        if GVProps=='':GVProps= NMtmpl("{height: 240, is3D: true,backgroundColor: '${bgncolor}$' ,legendBackgroundColor: 'gray',legendTextColor:'${lgntxtcol}$',legend:'label', enableTooltip:true,titleFontSize:0 }")
             
        self.insertActionScript("var nm_%02d_%s =new google.visualization.%s (document.getElementById('%s'));" % (self.VisCnt, elemId, GVpackage, elemId) )  
        self.insertActionScript("nm_%02d_%s.draw(%s , %s);" % (self.VisCnt, elemId,tablename, GVProps.render({'bgncolor':bgncolor, 'lgntxtcol':lgntxtcol})) )
    def _toStrOpen(self):
        self.GVpackages.contents=(self._JSloadPackages())
        return script._toStrOpen(self)      
    
    def _JSloadPackages(self):
        return "%s%s%s%s%s" % ("google.load('visualization', '", self.GVversion,"', {'packages':", str(self.packagesLst), "});" ) 
class GVtable(object):
    """ http://code.google.com/intl/el/apis/visualization/documentation/reference.html#DataTable
        rows ie: [ [ ['R0C0', 'R0C0-str', p], ['R0C1', 'R0C1-str', p]  ],
                                  [ ['R1C0', 'R1C0-str', p], ['R1C1', 'R1C1-str', p]  ], 
                                ] 
        list =[value or Null, format or Null if val==Null,  property] R=Row C=Column
         #rowExample =[[['r0c0'], ['r0c1'], ['r0c2']], [['r1c0'], ['r1c1'], ['r1c2']]]         
    """ 
    _Null ='Null'
    _Colheader=['type','id', 'label', 'type', 'p']
    #_CellHeader=['v:','f:', 'p:' ]
    GVversion='0.6'
    
    @classmethod
    def pyTojType(cls, ptype):
        """does not cater for date-time and all other types not imported here """ 
        for tpc in  [['number',float,  long, int],  ['string', unicode, str],  ['boolean', bool]]: 
            if  ptype in tpc[1:]: return tpc[0] 
        return None 
    def __init__(self, varname='gvdt',  rows=[], cols=[], tableProps='',  GVversion=False): 
        if GVversion: self.GVversion=GVversion 
        if tableProps !='':self.p= " p:\t%s" % tableProps
        else:self.p=''
        self.varname = varname 
        self.rows='{}'
        self.cols='{}'
        if rows!=[]:
            self.cols = self.setCols(cols, rows) 
            self.rows = self.setRows(rows)
          
    def setCols(self,cols, rows):   
        #print ['set cols', cols]
        #print ['set row', rows]
        
        def setCol(colNum,colType,colId='', colLabel='',  colProps=''):
            if colId == '':  colId= "col%d" % colNum 
            if colLabel !='':colLabel=", label: '%s'" % colLabel
            if colProps !='':colProps=", p: '%s'" % colProps 
            #{id: 'A', label: 'NEW A', type: 'string'}
            return "{id: '%s'%s, type: '%s'%s}" %(colId,colLabel, colType, colProps )
        
        columnsValues =  [ [it[0] for it in item if it[0] !=self._Null] for item in lst_transpose(rows, self._Null)]
        
        columnsValues=[columnsValues[0], [0 if item is None else item for item in columnsValues[1]]] 
        colsTypes =    [type_lcd(item) for item in columnsValues] 
        colsTypes =    [self.pyTojType(col[1]) for col in colsTypes]
        rt=' cols:\t[ \n'
        cnt=-1
        for col in colsTypes: 
            cnt +=1
            rt += "\t %s%s" % (setCol(cnt, col) ,  ',\n') 
        return rt[:-2] + '\n\t]'   
        
    def setRows(self,rows):
        def setRow():
            rowCols=''
            for col in row:
                rowCols += (self.setCell(col))+', '  
            return "{c:[%s]}" % rowCols[:-2] 
        rt=' rows:\t[ \n'
        for row in rows: 
            rt += "\t %s%s" % (setRow() ,  ',\n') 
        return rt[:-2] + '\n\t]'     
    def setCell(self, cellLst):
        def ValStr(vl):
            if   isinstance(vl, unicode):             return repr(vl).decode("raw-unicode-escape")[1:]
            elif isinstance(vl, str):                 return repr(str(vl))
            elif vl is None:                          return  0
            elif isinstance(vl, (int, long, float)):  return vl
            else: return  str(vl)
        Val=ValStr(cellLst[0]) 
        return "{v: %s%s%s}" % (Val, '' if len(cellLst) < 2 else  ", f: '%s'" % cellLst[1] , '' if len(cellLst) < 3 else ", f: %s" % cellLst[2] ) 
        
    def getContents(self):
        return "var %s = new google.visualization.DataTable(\n%s,\n %s\n)" % (self.varname,self.getDefinitions(), self.GVversion) 
    def getDefinitions(self): 
        return " {\n %s,\n %s\n %s\n }" %     (self.cols,  self.rows, self.p)  
    def unicode(self): return unicode(str(self))  
    __str__  =  getContents
    __call__ =  getContents    
  
  
def lst_transpose(lists=[], default=None):
    return map(lambda *row: [elem or default for elem in row], *lists)
def type_lcd (lst): 
    """least common denominator of types in lst returns [need conversion(True or False) , least common type] or None if no convertible type"""
    if len(lst) == 1:                                            return [False, type(lst[0])] 
    elif all([type(it)==type(lst[0])  for it in lst[1:]]):       return [False, type(lst[0])]
    else : 
        for tpc in [(long, int), (float, long, int), (unicode, str)]:
            if all([isinstance(it, tpc) for it in lst]):return [True, tpc[0]]
    return None        
 
class urlset(tag):   ##=sitemap
    def __init__(self): 
        tag.__init__(self)  
        self.attrSet('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9')
    def addUrl(self, loc,lastmod='', changefreq='weekly', priority='0.5' ):
        url=self.insertContents(tag(name='url'))
        url.insertContents(tag(loc, '', 'loc'))
        url.insertContents(tag(lastmod, '', 'lastmod'))
        url.insertContents(tag(changefreq, '', 'changefreq'))
        url.insertContents(tag(priority, '', 'priority'))
    def _toStrOpen(self):
        return  '<?xml version="1.0" encoding="UTF-8"?>\n' + tag._toStrOpen(self)  
class CDATA(tag):
    __slots__ =  []
    def _toStrOpen(self):
        return  u'[CDATA[' 
    def _toStrClose(self):
        return   u']]'                         
 
    
class rss(tag): 
    """ http://www.rssboard.org/rss-specification 
        time tm.strftime(NMutl.rfc2822_DATE_FMT, tm.gmtime()) 
    """
    (isMRSS, isDC, isGeo)=(False, False, False)
    class channel(tag):
        class title(tag): __slots__ =  []  
        class link(tag): __slots__ =  []
        class description(tag): __slots__ =  []     
        # ------------------------------------------------------  optional   
        class language(tag):        __slots__ =  [] 
        class copyright(tag):       __slots__ =  [] 
        class managingEditor(tag):  __slots__ =  [] 
        class webMaster(tag):       __slots__ =  [] 
        class pubDate(tag):         __slots__ =  [] 
        class lastBuildDate(tag):   __slots__ =  [] 
        class category(tag):        __slots__ =  [] 
        class generator(tag):       __slots__ =  [] 
        class docs(tag):            __slots__ =  [] 
        class ttl(tag):             __slots__ =  [] 
        
        class rating(tag):          __slots__ =  []
        class textInput(tag):       __slots__ =  []
        class skipHours(tag):       __slots__ =  []
        class skipDays(tag):        __slots__ =  []
        class image(tag):        
            class url(tag):         __slots__ =  []
            class title(tag):       __slots__ = []
            class link(tag):        __slots__ = []
            def __init__(self,url,  title, link): 
                tag.__init__(self)  
                self._url=self.insertContents(self.url(url))
                self._title=self.insertContents(self.title(title))
                self._link=self.insertContents(self.link(link)) 
        def addItem(self, title=None, link=None, description=None,pubDate=None,  guid=None):
            return self.insertContents(self.item(title, link, description,pubDate,  guid))
        class item(tag): 
            class title(tag): __slots__ =  []
            class link(tag): __slots__ =  [] 
            class guid(tag): __slots__ =  [] 
            class pubDate(tag): __slots__ =  [] 
            class description(tag): __slots__ =  [] 
            class author(tag): __slots__ =  []
            class category(tag): __slots__ =  []
            class comments(tag): __slots__ =  []
            class source(tag): __slots__ =  []
            class enclosure(tagNC):   
                def __init__(self,  **kargs): #url,length,type
                    tagNC.__init__(self)  
                    for k in kargs.keys():self.attrSet(k, kargs[k]) 
            class dc_creator(tagNC): 
                def __init__(self, creator): 
                    tagNC.__init__(self, creator,  name='dc:creator')  
            class georss_point(tag):  
                def __init__(self, boundingbox): 
                    tag.__init__(self,  boundingbox , name='georss:point')          
            class media_content(tag):
                #"""http://www.rssboard.org/media-rss"""
                def __init__(self, **kargs ): 
                    tag.__init__(self, name='media:content') 
                    for k in kargs.keys(): 
                        self.attrSet(k, kargs[k]) 
                def setFields(self, title, description):
                    self.insertContents(tag(title,'',  name='media:title'))
                    self.insertContents(tag(description, name='media:description'))
            class media_thumbnail(tagNC): 
                def __init__(self,  **kargs): 
                    tagNC.__init__(self, name='media:thumbnail')
                    for k in kargs.keys():self.attrSet(k, kargs[k])  
            def __init__(self, title, link=None, description=None,pubDate=None,  guid=None): 
                tag.__init__(self)  
                if guid is None:guid=link  
                self._title=None if title is None else self.insertContents(self.title(title)) 
                self._link= None if link is None else self.insertContents(self.link(link)) 
                self._guid=None if guid is None else self.insertContents(self.guid(guid)) 
                self._pubDate=None if pubDate is None else self.insertContents(self.pubDate(pubDate)) 
                self._description=None if description is None else self.insertContents(self.description(description))  
        def __init__(self, title, link, description):
            tag.__init__(self) 
            #$self.insertContents(tagNC( '','href=\"'+link+ '\"' +' type=\"application/rss+xml\" rel=\"self\"' ,  'atom:link'))
            self._title=self.insertContents(self.title(title))
            self._link=self.insertContents(self.link(link))
            self._description=self.insertContents(self.description(description))
    def __init__(self, channelTitle, channelLink, channelDescription, version="2.0", isMRSS=False, isDC=False, isGeo=False): 
        tag.__init__(self)  
        self.attrSet('version', version)
        (self.isMRSS, self.isDC, self.isGeo)=(isMRSS, isDC, isGeo)        
       
        self.isDC=isDC
        if isMRSS: self.attrSet( 'xmlns:media',  "http://search.yahoo.com/mrss/") 
        if isDC: self.attrSet('xmlns:dc',"http://purl.org/dc/elements/1.1/")  
        if isGeo:self.attrSet('xmlns:georss', "http://www.georss.org/georss")
        #----------------------------------------------------------------------------------------  
        self._channel=self.insertContents(self.channel(channelTitle, channelLink,  channelDescription))  
    def _toStrOpen(self):
        return  u'<?xml version="1.0" encoding="UTF-8"?>\n' + tag._toStrOpen(self)     
       
class html(tag): 
    if DocType == 1:
        headerDoctype='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'
    elif DocType == 0:
        headerDoctype='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
    else:
        headerDoctype='' 
    class head(tag):
        __slots__ =  ['headerDoctype'] 
        class meta(tag):
            __slots__ = []
            _nonclosing=True 
        class title(tag) :_slots__ =  []
        class link(tag)  :
            __slots__ = []
            _nonclosing=True
        def __init__(self):
            tag.__init__(self)  #[self.title('test')]
            #self.insertContents(self.meta()) 
    class body(tag):__slots__ = []
    def __init__(self):
        self.html_head=self.head()
        self.html_body=self.body()
        tag.__init__(self, [self.html_head, self.html_body], name='html')
    def _toStrOpen(self):
        return   tag._toStrOpen(self) if self.headerDoctype =='' else (self.headerDoctype +'\n' + tag._toStrOpen(self))  
        
class nmPage(html):
    def __init__(self):
        html.__init__(self)     
        if DocType == 0: self.attributes.contents='xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"'
    def columns(self,  widthsLst=[]):      
        rt=[]
        for dummy in widthsLst:
            rt.append(div('', 'class="nm-col"') )
      
class y_html(html):
    class width():
        doc1 = ['doc1', '750px']
        doc2 = ['doc2', '950px']
        doc3 = ['doc3', '100%']
        doc4 = ['doc4', '974px']
        doccustom = ['custom-doc','custom', 2]
    class sidebar():
        t1 = ['yui-t1','160L']  
        t2 = ['yui-t2','180L'] 
        t3 = ['yui-t3','300L'] 
        t4 = ['yui-t4','180R'] 
        t5 = ['yui-t5','240R'] 
        t6 = ['yui-t6','300R']
        t7 = ['yui-t7','None']                  # No side bar 
    class ydivider():
        g =['yui-g',  ['1/2', '1/2'] ]
        gb=['yui-gb', ['1/3', '1/3', '1/3'] ]  
        gc=['yui-gc', ['2/3', '1/3'] ]  
        gd=['yui-gd', ['1/3', '2/3'] ] 
        ge=['yui-ge', ['3/4', '1/4'] ]
        gf=['yui-gf', ['1/4', '3/4'] ]
        hd_ftInBody=False
   
    def __init__(self, width=width.doc4, sbar=sidebar.t1, bodyTopContents=''):
        html.__init__(self)     
        if DocType == 0: self.attributes.contents='xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"'
        if isinstance(width, int):
            self.doc_style=self.customwidth(width)
            self.html_head.insertContents(self.doc_style)
            width=self.width.doccustom  
        self.doc_hd=div('', 'id="hd"')  
        self.doc_ft=div('', 'id="ft"') 
        self.doc_bd_cnts=div('', 'class="yui-b"')            
        self.doc_bd_sidebar=None
        self.html_body.insertContents(bodyTopContents)
        if sbar != self.sidebar.t7:
            self.doc_bd.insertContents (div(self.doc_bd_cnts, 'id="yui-main"'))
            self.doc_bd_sidebar=div('','id="sidebar" class="yui-b"')
            self.doc_bd.insertContents (self.doc_bd_sidebar)
        else:
            self.doc_bd.insertContents(self.doc_bd_cnts)
        #self.doc_bd.insertContents(self.doc_bd_ft)
        self.doc=div( [ self.doc_hd,  self.doc_bd,  self.doc_ft ] )
        #self.doc.attrSet('id', width[0])
        self.doc.attrSetId(width[0])
        self.doc.attrSetClass(sbar[0] + ' nm_docmain')  # nm_docmain so we can get`it in css from this class since id and other class are document depentent  
        self.html_body.insertContents(self.doc)  
 
    def setdefaults(self, pageTitle='TL', ftConts='', mnuConts='', sidebarR=ydivider.gc, docclass=''):
        self.doc_ft.attrAppendClass ('nm-rad-bot nm-rad-paint') 
        if docclass !='': self.doc.attrAppendClass(docclass) 
        if sidebarR:
            self.MainRow=self.rowNew(divider=sidebarR,  appendTo=self.doc_bd_cnts)
            self.MainRow[0].attrSetId('nm-main-col')
            self.MainRow[1].attrSetId('nm-sbar_r')
        self.cntr_panel = self.doc_hd.insertContents (div( '' , 'id=\"cntrl-panel\"')) 
        self.headline=self.doc_hd.insertContents (div(h1(pageTitle), 'id=\"nm-headline\"')) 
        self.mnuConts=self.doc_hd.insertContents (div(mnuConts , 'id=\"nm-navcont\"' ) )  
        self.doc_ft.insertContents(ftConts)
    def  pageTitleGet(self):
        pass 
    def mainContentsAppend(self, row): 
        self.doc_bd_cnts.insertContents(row) 
    @classmethod
    def rowNew(cls, divider=ydivider.g, appendTo=None): 
        row=div() #div('', 'class="yui-u first nm-01"'))
        row.attrSetClass(divider[0])
        for i in range (len(divider[1])):
            rowDiv= div('', 'class="yui-u"')
            if i == 0: rowDiv.attrAppend('class', 'first')
            rowDiv.attrAppendCnt(i) 
            row.insertContents(rowDiv) 
        rowDiv.attrAppend('class', 'nm-last')
        if isinstance(appendTo, tag): appendTo.insertContents(row)
        return row 

#      @classmethod
#      def rowNew(cls, divider=ydivider.g, addcolumns=True, appendTo=None):
#          if addcolumns:
#              row=div(div('', 'class="yui-u first"'))
#              row.attrSetClass(divider[0])
#              for i in range (len(divider[1])-1):
#                  row.insertContents(div('', 'class="yui-u"')) 
#          else:
#              row = div('', 'class="yui-g"')    
#          if isinstance(appendTo, cls): appendTo.rowAppend(row)
#          return row 
    @classmethod
    def customwidth(self , width):   
        widthall = "width:%.2fem; "  % (width / 13.0)
        widthie  = "*width:%.2fem; " % (width / 13.3333)
        widthmin = "minwidth:%.0fpx " % width
        stl=style(' #custom-doc {margin:auto;text-align:left; ' + widthall + widthie + widthmin +'}','type="text/css"')
        return stl  

def rowCont(title, Contents, id=False, level=2) :
    Cont = div( )  
    if  id : Cont.attrSetId(id)
    Cont.attrSetClass("nm-lev-" + "%02d" % level)
    Cont.attrAppendCnt(level, 'nmlv-') 
    ContDivH1_6=div(h1_6(title,level))
    ContDivH1_6.attrSetClass('nm-c-lev-'+ "%02d" % level) 
    Cont.insertContents(ContDivH1_6)
    Cont.insertContents(Contents)
    Cont.insertContents(div('', 'class=\"nm-dummy-last\"'))
    return Cont    
def testTag():
    b=div()
    for i in range (0, 4):
        d=div()
        d.attrSet('id', 'id-' + str(i))
        for j in range (0, 3):
            par=p('PTxt')
            par.attrSet('id', 'id-' + str(i) + '-' + str(j))
            d.insertContents(par) 
        b.insertContents(d)
    return b
def TxtShift(txt, shiftstr):
    rt = shiftstr + txt 
    return(rt.replace('\n', '\n'+shiftstr))



#clas templ()

#import  NMtbl as NMtbl
#geotb=NMtbl.NMtable()
#geotb.CSVload('/home/milon/gae/appls/milon/geodump.csv',3, skipValidations=True)
#ht=TblToHtml(geotb) 
#def TblToHtml(tbl, lng='en'): 
#    cols=[item for item in tbl.ColumnKeysByWBC() if not item.endswith('@date')]
#    headlst = [tbl.Columns[item].GetTitle()[lng] for item in cols] 
#    rowlst  = [[str(tbl[row].get(col,geotb.missingvalue)) for col in cols] for row in tbl] 
#    htmltable=table(contentslst = rowlst, attributes='border="\"1\"',caption = lng, headerlst = headlst, footerlst= False, tagColums=False) 
#    return htmltable
